package com.googlecode.dgwt.client.dojo.core;

import java.util.List;

/**
 * @author wellsantos@wellsantos.com
 * @since 0.01
 */
public class JsMap<V> extends JsObject {


    protected JsMap() {
    }

    
    public static <T extends Object> JsMap<T> create() {
        return createObject().cast();
    }


    public static native <T extends Object> JsMap<T> as(Object obj) /*-{
        return obj;
    }-*/;


    public final native boolean containsKey(String key)/*-{
        return this.hasOwnProperty(key);
    }-*/;

    
    public final native V get(String key) /*-{
        return this[key];
    }-*/;

    
    public final native List<String> keySet(int capacity) /*-{
        var s = @java.util.ArrayList::new(I)(capacity);
        for(var key in this) {
            if (!this.hasOwnProperty(key)) continue;
            s.@java.util.ArrayList::add(Ljava/lang/Object;)(key);
        }
        return s;
    }-*/;

    
    public final native void set(String key, V value) /*-{
        this[key] = value;
    }-*/;


    public final native V put(String key, V value) /*-{
        var previous = this[key];
        this[key] = value;
        return previous;
    }-*/;

    
    public final native V remove(String key) /*-{
        var previous = this[key];
        delete this[key];
        return previous;
    }-*/;

    
    public final native int size() /*-{
        var count = 0;
        for(var key in this) {
            if (this.hasOwnProperty(key)) ++count;
        }
        return count;
    }-*/;

    
    public final native List<V> getValues(List<V> list) /*-{
        var s = list ? list : @java.util.ArrayList::new()();
        for(var key in this) {
            if (!this.hasOwnProperty(key)) continue;
            s.@java.util.List::add(Ljava/lang/Object;)(this[key]);
        }
        return s;
    }-*/;
    
    
    public final native V[] getValues() /*-{
        var a=[];
        for(var key in this) {
            if (!this.hasOwnProperty(key)) continue;
            a[a.length] = key;
        }
        return a;
    }-*/;

    
    public final native JsArray<V> getNativeValues() /*-{
        var a=[];
        for(var key in this) {
            if (!this.hasOwnProperty(key)) continue;
            a[a.length] = key;
        }
        return a;
    }-*/;


    public final native boolean containsValue(Object value) /*-{
        for(var key in this) {
            if (!this.hasOwnProperty(key)) continue;
            var val = this[key];
            if (val == value || (value != null 
                    && value.@java.lang.Object::equals(Ljava/lang/Object;)(val))){
                return true;
            }
        }
        return false;
    }-*/;
    
}
